/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Cyberoam.java
 *
 * Created on Dec 20, 2011, 11:43:06 PM
 */
package cyberoam;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;
import javax.crypto.*;
import javax.swing.*;
import javax.swing.Timer;

/**
 *
 * @author SiyaRam
 */
public class Cyberoam extends javax.swing.JFrame implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            //JOptionPane.showMessageDialog(this, "u" + username + "p" + password);
            login();
            icon.displayMessage("Cyberoam Session Expired", "Automatically logging in...", TrayIcon.MessageType.INFO);
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            //ex.printStackTrace();
        }
    }

    private enum UserAction {

        LOGIN, LOGOUT
    };
    private String username;
    private String password = "";
    private char[] passwd;
    private boolean isChecked;
    private StringBuilder response;
    private String loginurl;
    private String logouturl;
    private UserAction action = UserAction.LOGIN;
    private Timer timer;
    Map<String, String> data;
    ResourceBundle rb = ResourceBundle.getBundle("bundle.Configuration");
    private String filePath;
    private File file;
    private TrayIcon icon;

    /** Creates new form Cyberoam */
    public Cyberoam() {
        ObjectInputStream ois = null;
        try {
            initComponents();
            filePath = System.getProperty("user.home");
            String fileSeparator = System.getProperty("file.separator");
            filePath = filePath + fileSeparator + rb.getString("file_name");
            //JOptionPane.showMessageDialog(this, filePath);
            File f = new File(filePath);
            if (f.exists()) {
                ois = new ObjectInputStream(new FileInputStream(f));
                username = (String) ois.readObject();
                //System.out.println(username);
                txtUsername.setText(username);
                password = (String) ois.readObject();
                SecretKey key = (SecretKey) ois.readObject();
                DESEncrypter encrypter = new DESEncrypter(key);
                password = encrypter.decrypt(password);
                //System.out.println(password);
                txtPassword.setText(password);
                passwd = password.toCharArray();
                ois.close();
            }
        } catch (IOException | ClassNotFoundException ex) {
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        ContentPanel = new javax.swing.JPanel();
        lblUsername = new javax.swing.JLabel();
        lblPassword = new javax.swing.JLabel();
        txtUsername = new javax.swing.JTextField();
        txtPassword = new javax.swing.JPasswordField();
        chkKeepMeLoggedIn = new javax.swing.JCheckBox();
        btnLogin = new javax.swing.JButton();
        btnCancel = new javax.swing.JButton();
        lblStatus = new javax.swing.JLabel();
        HeaderPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        addWindowStateListener(new java.awt.event.WindowStateListener() {
            public void windowStateChanged(java.awt.event.WindowEvent evt) {
                formWindowStateChanged(evt);
            }
        });

        ContentPanel.setName("ContentPanel"); // NOI18N

        lblUsername.setText("Enter Username");
        lblUsername.setName("lblUsername"); // NOI18N

        lblPassword.setText("Enter Password");
        lblPassword.setName("lblPassword"); // NOI18N

        txtUsername.setName("txtUsername"); // NOI18N

        txtPassword.setHorizontalAlignment(javax.swing.JTextField.LEFT);
        txtPassword.setName("txtPassword"); // NOI18N

        chkKeepMeLoggedIn.setSelected(true);
        chkKeepMeLoggedIn.setText("Save my credentials");
        chkKeepMeLoggedIn.setName("chkKeepMeLoggedIn"); // NOI18N
        chkKeepMeLoggedIn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkKeepMeLoggedInActionPerformed(evt);
            }
        });

        btnLogin.setText("Login");
        btnLogin.setName("btnLogin"); // NOI18N
        btnLogin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLoginActionPerformed(evt);
            }
        });

        btnCancel.setText("Exit");
        btnCancel.setName("btnCancel"); // NOI18N
        btnCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCancelActionPerformed(evt);
            }
        });

        lblStatus.setForeground(new java.awt.Color(255, 0, 0));
        lblStatus.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblStatus.setName("lblStatus"); // NOI18N

        javax.swing.GroupLayout ContentPanelLayout = new javax.swing.GroupLayout(ContentPanel);
        ContentPanel.setLayout(ContentPanelLayout);
        ContentPanelLayout.setHorizontalGroup(
            ContentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ContentPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ContentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, ContentPanelLayout.createSequentialGroup()
                        .addGroup(ContentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, ContentPanelLayout.createSequentialGroup()
                                .addComponent(lblUsername)
                                .addGap(18, 18, 18)
                                .addComponent(txtUsername, javax.swing.GroupLayout.PREFERRED_SIZE, 126, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, ContentPanelLayout.createSequentialGroup()
                                .addComponent(lblPassword)
                                .addGap(21, 21, 21)
                                .addComponent(txtPassword))
                            .addComponent(chkKeepMeLoggedIn, javax.swing.GroupLayout.Alignment.LEADING))
                        .addGap(89, 89, 89))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, ContentPanelLayout.createSequentialGroup()
                        .addComponent(lblStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 374, Short.MAX_VALUE)
                        .addContainerGap())))
            .addGroup(ContentPanelLayout.createSequentialGroup()
                .addGap(126, 126, 126)
                .addComponent(btnLogin)
                .addGap(18, 18, 18)
                .addComponent(btnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(132, Short.MAX_VALUE))
        );
        ContentPanelLayout.setVerticalGroup(
            ContentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ContentPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ContentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblUsername, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtUsername, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(ContentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addComponent(chkKeepMeLoggedIn)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(lblStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 22, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(ContentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnCancel)
                    .addComponent(btnLogin))
                .addGap(15, 15, 15))
        );

        HeaderPanel.setBackground(new java.awt.Color(51, 153, 255));
        HeaderPanel.setForeground(new java.awt.Color(255, 255, 255));
        HeaderPanel.setName("HeaderPanel"); // NOI18N
        HeaderPanel.setPreferredSize(new java.awt.Dimension(267, 176));

        jLabel1.setForeground(new java.awt.Color(255, 255, 255));
        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setText("Cyberoam Client");
        jLabel1.setName("jLabel1"); // NOI18N

        javax.swing.GroupLayout HeaderPanelLayout = new javax.swing.GroupLayout(HeaderPanel);
        HeaderPanel.setLayout(HeaderPanelLayout);
        HeaderPanelLayout.setHorizontalGroup(
            HeaderPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(HeaderPanelLayout.createSequentialGroup()
                .addGap(161, 161, 161)
                .addComponent(jLabel1)
                .addContainerGap(154, Short.MAX_VALUE))
        );
        HeaderPanelLayout.setVerticalGroup(
            HeaderPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 27, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(HeaderPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 394, Short.MAX_VALUE)
                    .addComponent(ContentPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(HeaderPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(ContentPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnLoginActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoginActionPerformed

        // check whether the input values are provided or not.
        String errorMessage = null;
        username = txtUsername.getText();
        passwd = txtPassword.getPassword();
        isChecked = chkKeepMeLoggedIn.isSelected();
        if (username.isEmpty()) {
            errorMessage = "Please provide Username";
            JOptionPane.showMessageDialog(this, errorMessage);
            txtUsername.requestFocusInWindow();
            return;
        } else if (passwd.length == 0) {
            errorMessage = "Please provide Password";
            JOptionPane.showMessageDialog(this, errorMessage);
            txtPassword.requestFocusInWindow();
            return;
        }

        //read the password into String
        password = "";
        for (char c : passwd) {
            password += c;
        }

        try {

            collectData();

            if (action == UserAction.LOGIN) {

                if (isChecked) {
                    try {
                        SecretKey key = KeyGenerator.getInstance("DES").generateKey();
                        //System.out.println(key.toString());
                        DESEncrypter encrypter = new DESEncrypter(key);

                        String encrypted_password = encrypter.encrypt(password);
                        //System.out.println(encrypter.decrypt(encrypted_password));
                        file = new File(filePath);
                        if (file.exists()) {
                            file.delete();
                        }
                        file.createNewFile();
                        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
                        oos.writeObject(username);
                        oos.writeObject(encrypted_password);
                        oos.writeObject(key);
                        oos.close();

                    } catch (IOException | NoSuchAlgorithmException ex) {
                        ex.printStackTrace();
                    }

                }

                login();

            } else {

                logout();

            }

            action = (response.indexOf("LIVE") == -1) ? UserAction.LOGIN : UserAction.LOGOUT;

            if (action == UserAction.LOGIN) {
                btnLogin.setText(rb.getString("loginbuttontext"));
            } else {
                if (timer == null) {
                    timer = new Timer(Integer.parseInt(rb.getString("timeout_minutes")) * 60 * 1000, this);
                    //timer=new Timer(2000,this);
                    timer.start();
                }
                btnLogin.setText(rb.getString("logoutbuttontext"));
            }
            //JOptionPane.showMessageDialog(this, action);

            //if checkbox is not selected then remove the credentials stored into the file.
            if (!isChecked) {
                file = new File(filePath);
                if (file.exists()) {
                    file.delete();
                }
            }
        } catch (Exception e) {
            System.out.println("ex" + e.getMessage() + e.getClass());
        } finally {
        }

    }//GEN-LAST:event_btnLoginActionPerformed

    private void collectData() {

        data = new HashMap<>();
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        long milliseconds = cal.getTimeInMillis();
        data = new HashMap<>();
        data.put("username", username);
        data.put("a", String.valueOf(milliseconds));

        if (action == UserAction.LOGIN) {
            //JOptionPane.showMessageDialog(this, rb.getString("url"));                
            data.put("mode", "191");
            data.put("password", password);
            //JOptionPane.showMessageDialog(this, password.toString());                            
        } else {
            data.put("mode", "193");
        }
    }

    private void login() throws Exception {
        loginurl = rb.getString("loginurl");
        response = doSubmit(loginurl, data);
        setResponse();
    }

    private void logout() throws Exception {
        logouturl = rb.getString("logouturl");
        response = doSubmit(logouturl, data);
        setResponse();
    }

    private void setResponse() {
        int start = response.lastIndexOf("<message>");
        int end = response.indexOf("</message>");
        lblStatus.setText(response.substring(start + "<message>".length(), end));
    }

    private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
        // TODO add your handling code here:
        System.exit(0);
    }//GEN-LAST:event_btnCancelActionPerformed

    private void chkKeepMeLoggedInActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkKeepMeLoggedInActionPerformed
        // TODO add your handling code here:
        AbstractButton abstractButton = (AbstractButton) evt.getSource();
        isChecked = abstractButton.getModel().isSelected();
        //JOptionPane.showMessageDialog(null, isChecked);
    }//GEN-LAST:event_chkKeepMeLoggedInActionPerformed

    private void formWindowStateChanged(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowStateChanged
        // TODO add your handling code here:
        SystemTray tray = SystemTray.getSystemTray();
        PopupMenu popup = new PopupMenu();
        MenuItem login = new MenuItem("Login");
        login.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                collectData();
                try {
                    login();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
        MenuItem logout = new MenuItem("Logout");
        logout.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                collectData();
                try {
                    logout();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
        MenuItem exit = new MenuItem("Exit");
        exit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        popup.add(login);
        popup.add(logout);
        popup.add(exit);
        //JOptionPane.showMessageDialog(this, tray.isSupported());        
        Image image = Toolkit.getDefaultToolkit().createImage("connect.png");
        icon = new TrayIcon(image, "CyberoamClient", popup);
        try {
            tray.add(icon);            
        } catch (AWTException e) {
            System.out.println(e.getMessage());
        }
    }//GEN-LAST:event_formWindowStateChanged

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Cyberoam.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Cyberoam.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Cyberoam.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Cyberoam.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new Cyberoam().setVisible(true);
            }
        });
    }

    public StringBuilder doSubmit(String url, Map<String, String> data) throws Exception {
        URL siteUrl = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) siteUrl.openConnection();

        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setDoInput(true);

        DataOutputStream out = new DataOutputStream(conn.getOutputStream());

        Set keys = data.keySet();
        Iterator keyIter = keys.iterator();
        String content = "";
        for (int i = 0; keyIter.hasNext(); i++) {
            Object key = keyIter.next();
            if (i != 0) {
                content += "&";
            }
            content += key + "=" + URLEncoder.encode(data.get(key), "UTF-8");
        }
        //System.out.println(content);
        out.writeBytes(content);
        out.flush();
        out.close();
        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line = "";
        StringBuilder res = new StringBuilder();
        while ((line = in.readLine()) != null) {
            res.append(line);
        }
        //System.out.println(res);
        in.close();
        return res;
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel ContentPanel;
    private javax.swing.JPanel HeaderPanel;
    private javax.swing.JButton btnCancel;
    private javax.swing.JButton btnLogin;
    private javax.swing.JCheckBox chkKeepMeLoggedIn;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel lblPassword;
    private javax.swing.JLabel lblStatus;
    private javax.swing.JLabel lblUsername;
    private javax.swing.JPasswordField txtPassword;
    private javax.swing.JTextField txtUsername;
    // End of variables declaration//GEN-END:variables
}
